package com.limingru.newbee.config.handler;

import com.limingru.newbee.api.vo.UserVO;
import com.limingru.newbee.common.NewBeeMallException;
import com.limingru.newbee.common.ServiceResultEnum;
import com.limingru.newbee.config.annotation.TokenToUser;
import com.limingru.newbee.dao.UserTokenMapper;
import com.limingru.newbee.entity.User;
import com.limingru.newbee.entity.UserToken;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

@Component
public class TokenToUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private UserTokenMapper userTokenMapper;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        if (methodParameter.hasParameterAnnotation(TokenToUser.class)) {
            return true;
        }
        return false;
    }

    @Nullable
    @Override
    public Object resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, @Nullable WebDataBinderFactory webDataBinderFactory) throws Exception {
        if (methodParameter.getParameterAnnotation(TokenToUser.class) instanceof TokenToUser) {
            String token = nativeWebRequest.getHeader("token");
            if (!StringUtils.isEmpty(token)) {
                UserVO userVO = userTokenMapper.selectUserByToken(token);
                if (userVO == null) {
                    NewBeeMallException.fail(ServiceResultEnum.USER_IS_NULL.getText());
                }
                UserToken userToken = userTokenMapper.selectByUserId(userVO.getUserId());
                if (userToken.getExpireTime().getTime() <= System.currentTimeMillis()) {
                    NewBeeMallException.fail(ServiceResultEnum.LOGIN_HAS_EXPIRED.getText());
                }
                if (userVO.getLockedFlag() == 1) {
                    NewBeeMallException.fail(ServiceResultEnum.LOGIN_ERROR_LOCKED_ERROR.getText());
                }
                User user = new User();
                BeanUtils.copyProperties(userVO, user);
                return user;
            } else {
                NewBeeMallException.fail(ServiceResultEnum.NOT_LOGIN_ERROR.getText());
            }
        }
        return null;
    }
}
